﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Game_Field
{
    class NodeGameLogic
    {
        Random rndgen;
        List<GameNode> nodesList = new List<GameNode>();
        GameField gameField;
        Drawer drawer;
        private int nodeCount;
        List<GameNode> winnersList = new List<GameNode>();
        GameNode exit = new GameNode(0, 0, '@');



        public NodeGameLogic(GameField gameField, Drawer drawer, int nodeCount)
        {
            this.rndgen = new Random();
            this.gameField = gameField;
            this.drawer = drawer;
            this.nodeCount = nodeCount;
        }

        public void StartGame()
        {

            drawer.DrawGameField(gameField, '*');
            GenerateRrandomNodes();

            for (int i = 0; i < 5000; i++)
            {
                foreach (GameNode node in nodesList)
                {
                    int choiceNodeMove = rndgen.Next(1, 5);
                    drawer.ClearGameNode(node);
                    switch (choiceNodeMove)
                    {
                        case 1:
                            {
                                if (IsMovable(node.NodeX, node.NodeY + 1) && IsOnField(node.NodeX, node.NodeY + 1))
                                {
                                    node.MoveDown();
                                }
                                break;
                            }

                        case 2:

                            if (IsMovable(node.NodeX, node.NodeY - 1) && IsOnField(node.NodeX, node.NodeY - 1))
                            {
                                node.MoveUp();
                            }
                            break;

                        case 3:
                            if (IsMovable(node.NodeX - 1, node.NodeY) && IsOnField(node.NodeX - 1, node.NodeY))
                            {
                                node.MoveLeft();
                            }
                            break;

                        case 4:
                            if (IsMovable(node.NodeX + 1, node.NodeY) && IsOnField(node.NodeX + 1, node.NodeY))
                            {
                                node.MoveRight();
                            }
                            break;
                    }
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    drawer.DrawGameNode(node);
                    Console.ForegroundColor = ConsoleColor.White;
                }
            }
        }

        public void StartChairGame()
        {

            drawer.DrawGameField(gameField, '*');
            GenerateRrandomNodes();
            GenerateExit();

            do
            {
                Console.Clear();
                winnersList.Clear();
                drawer.DrawGameField(gameField, '*');
                GenerateNodeCoordinates();
                GenerateExit();
                for (int i = 0; i < nodesList.Count; i++)
                {
                    drawer.DrawGameNode(nodesList[i]);
                }
                Console.ForegroundColor = ConsoleColor.Red;
                drawer.DrawGameNode(exit);
                Console.ForegroundColor = ConsoleColor.White;
                do
                {
                    for (int i = 0; i < nodesList.Count; i++)
                    {
                        int choiceNodeMove = rndgen.Next(1, 5);
                        drawer.ClearGameNode(nodesList[i]);
                        switch (choiceNodeMove)
                        {
                            case 1:

                                if (IsMovable(nodesList[i].NodeX, nodesList[i].NodeY + 1) && IsOnField(nodesList[i].NodeX, nodesList[i].NodeY + 1))
                                {
                                    nodesList[i].MoveDown();
                                }
                                break;


                            case 2:

                                if (IsMovable(nodesList[i].NodeX, nodesList[i].NodeY - 1) && IsOnField(nodesList[i].NodeX, nodesList[i].NodeY - 1))
                                {
                                    nodesList[i].MoveUp();
                                }
                                break;

                            case 3:
                                if (IsMovable(nodesList[i].NodeX - 1, nodesList[i].NodeY) && IsOnField(nodesList[i].NodeX - 1, nodesList[i].NodeY))
                                {
                                    nodesList[i].MoveLeft();
                                }
                                break;

                            case 4:
                                if (IsMovable(nodesList[i].NodeX + 1, nodesList[i].NodeY) && IsOnField(nodesList[i].NodeX + 1, nodesList[i].NodeY))
                                {
                                    nodesList[i].MoveRight();
                                }
                                break;
                        }
                        drawer.DrawGameNode(nodesList[i]);

                        if (IsExitFound())
                        {
                            drawer.ClearGameNode(nodesList[i]);                            
                            Console.ForegroundColor = ConsoleColor.Red;
                            drawer.DrawGameNode(exit);
                            Console.ForegroundColor = ConsoleColor.White;
                            winnersList.Add(nodesList[i]);
                            nodesList.Remove(nodesList[i]);
                        }

                    }
                } while (nodesList.Count > 1);

                Console.SetCursorPosition(gameField.Width + gameField.GameFieldX + 5, gameField.GameFieldY);
                Console.WriteLine("Winners");
                for (int i = 0; i < winnersList.Count; i++)
                {
                    Console.SetCursorPosition(gameField.Width + gameField.GameFieldX + 5, gameField.GameFieldY + 2 + i);
                    Console.WriteLine(winnersList[i].NodeSymbol);
                }

                Console.SetCursorPosition(gameField.Width + gameField.GameFieldX + 15, gameField.GameFieldY);
                Console.WriteLine("Loosers");
                for (int i = 0; i < nodesList.Count; i++)
                {
                    Console.SetCursorPosition(gameField.Width + gameField.GameFieldX + 15, gameField.GameFieldY + 2 + i);
                    Console.WriteLine(nodesList[i].NodeSymbol);
                }
                nodesList.Clear();

                for (int i = 0; i < winnersList.Count; i++)
                {
                    
                    nodesList.Add(winnersList[i]);
                }
                

                Console.ReadKey();
                

            } while (winnersList.Count > 1);
        }


        public bool IsMovable(int x, int y)
        {
            foreach (var n in nodesList)
                if (n.NodeX == x && n.NodeY == y)
                    return false;
            return true;
        }

        public void GenerateRrandomNodes()
        {
            for (int i = 0; i < nodeCount; i++)
            {
                int newX = rndgen.Next(gameField.GameFieldX, (gameField.Width + gameField.GameFieldX - 1));
                int newY = rndgen.Next(gameField.GameFieldY + 1, (gameField.Height + gameField.GameFieldY - 1));
                if (IsMovable(newX, newY))
                {
                    nodesList.Add(new GameNode(newX, newY, (Char)(i + 20)));
                }
                else
                {
                    i--;
                }
            }
        }

        public void GenerateNodeCoordinates()
        {
            for (int i = 0; i < nodesList.Count; i++)
            {
                int newX = rndgen.Next(gameField.GameFieldX, (gameField.Width + gameField.GameFieldX - 1));
                int newY = rndgen.Next(gameField.GameFieldY + 1, (gameField.Height + gameField.GameFieldY - 1));
                if (IsMovable(newX, newY))
                {
                    nodesList[i].NodeX = newX;
                    nodesList[i].NodeY = newY;
                }
            }

        }

        public void GenerateExit()
        {
            for (int i = 0; i < 1; i++)
            {
                int newX = rndgen.Next(gameField.GameFieldX, (gameField.Width + gameField.GameFieldX - 1));
                int newY = rndgen.Next(gameField.GameFieldY + 1, (gameField.Height + gameField.GameFieldY - 1));
                if (IsMovable(newX, newY))
                {
                    exit.NodeX = newX;
                    exit.NodeY = newY;
                    exit.NodeSymbol = (char) rndgen.Next(64, 65);
                }
                else
                {
                    i--;
                }
            }
        }

        public bool IsOnField(int x, int y)
        {
            if (x < gameField.GameFieldX || x > gameField.GameFieldX + gameField.Width - 1 || y < gameField.GameFieldY || y > gameField.GameFieldY + gameField.Height - 1)
                return false;
            return true;
        }

        public bool IsExitFound ()
        {
            for (int i = 0; i < nodesList.Count; i++)
            {
                if (nodesList[i].NodeX == exit.NodeX && nodesList[i].NodeY == exit.NodeY)
                {
                    return true;
                }
            }
            return false;
        }

    }
}
